"""Generic commands primarily used for testing the command channel system."""
import sys
from time import sleep

import unixutils.testing.asserts as asserts
from unixutils.privsep.command import CommandPackage, Command, argtypes, obj, \
	find_commands

__all__ = ['Hello', 'Exit', 'GenericCommands']

# pylint: disable-msg=R0201

class Hello(Command):
	"""Cause the receiver to print "Hello %r" to stdout.

	This serves no purpose except for testing.

	NAME: 'HELLO'
	ARGS:
		name (obj): the thing to be printed out.
	"""

	hello_list = ["Biotches!", "everybody!"]

	def __init__(self):
		"""Init."""
		Command.__init__(self, "HELLO")

	def handle(self, _, name):
		"""Print out a message using the name provided by the caller.
		Return the name to the caller.
		"""
		print "handle(): Hello %r" % name
		return name

	def invoke(self, ctx, name):
		"""Cause the callee to print out a message."""
		print "Sending: %r for hello." % name
		ctx.channel.push(self, name)

	def test_parent(self, ctx):
		"""Test the callee side of HELLO."""
		for hello in Hello.hello_list:
			for _ in range(0, 2):
				(_, result) = ctx.channel.service_call(ctx.command)

				asserts.assert_(
					hello == result,
					"Wanted %r, got %r" % (result, hello)
				)

	def test_child(self, ctx):
		"""Test the caller side of HELLO."""
		for hello in Hello.hello_list:
			ctx.channel.call(ctx.command, hello)
			ctx.channel.call(ctx.command, name=hello)

class Exit(Command):
	"""Cause the receiver to exit cleanly.

	NAME: 'EXIT'
	ARGS:
		delay (float): specifies an amount of time for the other side
			to sleep before exiting.
	KWARGS:
		val (int): value to provide to exit().
	"""
	def __init__(self):
		"""Init."""
		Command.__init__(self, "EXIT")

	@argtypes(obj, obj, delay=float, val=int)
	def handle(self, _, delay=0, val=0):
		"""Sleep for the number of seconds specified by the caller in
		`delay', then exit with a return code of `val'."""
		sleep(delay)
		sys.exit(val)

	@argtypes(obj, obj, delay=float, val=int)
	def invoke(self, ctx, delay=0, val=0):
		"""Cause the callee to exit after `delay' seconds with a return
		code of `val'.
		"""
		ctx.channel.push(self, delay, val)

# pylint: disable-msg=C0103,W0142
GenericCommands = CommandPackage(*find_commands(locals()))
